home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / PowerD / rtgmaster / examples / chunky / nfs.d next >
Encoding:
Text File  |  2002-10-28  |  11.7 KB  |  524 lines

  1. // this is just an example, if You would like to use it's engine, You will have very much work
  2. // with it to make it not that limited. It's 'optimised' for only this one track!
  3. // it's also 'optimised' to 320x240 resolition, if You will enlarge it, it may not look very well.
  4. // etc. etc. It also shows how to use the RTGMaster's doublebuffering and the DrawTriangle()
  5. // function usage from the chunky.lib (included in the PowerD archive or lib/ directory)
  6.  
  7. MODULE    'rtgmaster',
  8.             'rtgmaster/rtgmaster',
  9.             'rtgmaster/rtgc2p',
  10.             'rtgmaster/rtgsublibs',
  11.             'rtgmaster/rtgami'
  12. MODULE    'exec/memory',
  13.             'utility/tagitem',
  14.             'intuition/screens',
  15.             'intuition/intuition'
  16. MODULE    'lib/chunky'                // this contains the DrawTriangle() function reference
  17.  
  18. DEF    nbuf=0,    // rendering buffer
  19.         c2psig,    // c2p signal
  20.  
  21.         width,    // buffer dimensions
  22.         height
  23.  
  24. // if enabled, there will be some output statistics per each frame rendered
  25. //#define GET_TIME TRUE
  26.  
  27. PROC Go(rsc:PTR TO RtgScreenAMI,chunky:PTR TO chunky,track:PTR TO track)
  28.     DEF    n=0,imsg:PTR TO IntuiMessage,c:PTR TO camera
  29.     DEFD    micros,sum_micros
  30.     c:=[
  31.         track.line[track.pos].x,track.line[track.pos].y+1.0,track.line[track.pos].z,
  32.           0.0,0.00,0.0,
  33.           1.0,1.00,1.0,
  34.           0.0,0.00,0.0,
  35.           100.0]:camera
  36.     WHILE n<4096
  37.         IF imsg:=RtgGetMsg(rsc)
  38.             SELECT imsg.Class
  39.             CASE IDCMP_MOUSEBUTTONS
  40.             CASE IDCMP_RAWKEY
  41.                 SELECT imsg.Code AND $ff
  42.                 CASE $4f;    c.ay-=0.03
  43.                 CASE $4e;    c.ay+=0.03
  44. //                CASE $4c;    car.uacc:=car.acceleration
  45. //                CASE $4d;    car.uacc:=-car.acceleration
  46. //                CASE $cc,$cd;    car.uacc:=0
  47. //                CASE $cf,$ce;    car.udir:=0
  48.                 CASE $40
  49.                 ENDSELECT
  50.             ENDSELECT
  51.             RtgReplyMsg(rsc,imsg)
  52.         ENDIF
  53. //        MoveCar(car,track)
  54. //        c.z+=2
  55.  
  56.         FillChunky(chunky,3)
  57.  
  58.         sum_micros:=0.0
  59.         polycount:=polydraw:=transcount:=0
  60.         ReadEClock(time0)
  61.  
  62.         RenderTrack(chunky,track,c)
  63.  
  64.         ReadEClock(time1)
  65.         micros:=(time1.Lo-time0.Lo)*micros_per_eclock
  66.         sum_micros+=micros
  67.  
  68.         MoveCamera(c,track,micros)
  69.  
  70. #ifdef GET_TIME
  71.         PrintF('\d[4]: \d[6] \d[6] \d[6] \d[9] µs\n',n,polycount,polydraw,transcount,micros)
  72. #endif
  73.     EXITIF ChangeBuffer(rsc,chunky)=FALSE
  74.         n++
  75.     EXITIF Mouse()=2
  76.     ENDWHILE
  77. ENDPROC
  78.  
  79. PROC ChangeBuffer(rsc:PTR TO RtgScreen,chunky:PTR TO chunky)(LONG)
  80.     DEF    buf
  81.     IF buf:=GetBufAdr(rsc,nbuf)
  82.         CopyRtgBlit(rsc,buf,chunky.pixel,0,0,0,chunky.wi,chunky.he,chunky.wi,chunky.he,0,0)
  83.         RtgWaitTOF(rsc)
  84.         SwitchScreens(rsc,nbuf)
  85.         IF nbuf=2 THEN nbuf:=0
  86.     ELSE RETURN FALSE
  87. ENDPROC TRUE
  88.  
  89. DEF    RTGMasterBase
  90.  
  91. PROC main()
  92.     DEF    req:PTR TO ScreenReq,
  93.             rsc:PTR TO RtgScreen,
  94.             ch:PTR TO chunky,ok,
  95.             track:PTR TO track
  96.     DEF    tags:PTR TO TagItem
  97.  
  98.     // open the rtgmaster.library
  99.     IF RTGMasterBase:=OpenLibrary('rtgmaster.library',23)
  100.  
  101.         // open the rtg screen requester to select screenmode and dimensions
  102.         IF req:=RtgScreenModeReq([
  103.                 smr_MinWidth,320,
  104.                 smr_MinHeight,200,
  105.                 smr_MaxWidth,1024,
  106.                 smr_MaxHeight,768,
  107.                 smr_ChunkySupport,512,
  108.                 smr_PlanarSupport,-1,
  109.                 smr_Buffers,2,                                // double buffering
  110.                 smr_PrefsFileName,'simul.prefs',        // preferences file
  111.                 TAG_END])
  112.  
  113.             // open requested screen
  114.             IF rsc:=OpenRtgScreen(req,NIL)
  115.  
  116.                 GetRtgScreenData(rsc,tags:=[
  117.                     grd_Width,0,
  118.                     grd_Height,0,
  119.                     TAG_END])
  120.                 width:=tags[0].Data
  121.                 height:=tags[1].Data
  122.  
  123.                 IF RtgInitRDCMP(rsc)
  124.  
  125.                     // get c2p signal
  126.                     IF (c2psig:=AllocSignal(-1))<>-1
  127.  
  128.                         // lock the screen for private use
  129.                         LockRtgScreen(rsc)
  130.  
  131.                         // setup colours of the screen
  132.                         LoadPalette(rsc,'palette')
  133.  
  134.                         IF pool:=CreatePool(MEMF_PUBLIC|MEMF_CLEAR,16384,2048)
  135.                             IF ok,track:=LoadTrack(0)
  136.                                 IF ch:=CreateChunky(width,height)
  137.  
  138.                                     IF get_timer()
  139.                                         Go(rsc,ch,track)
  140.                                         free_timer()
  141.                                     ENDIF
  142.                                     DeleteChunky(ch)
  143.  
  144.                                 ELSE PrintF('Not enough memory!\n')
  145.                                 UnLoadTrack(track)
  146.                             ENDIF
  147.                             DeletePool(pool)
  148.                         ELSE PrintF('Not enough memory!\n')
  149.  
  150.                         // unlock locked screen
  151.                         UnlockRtgScreen(rsc)
  152.  
  153.                         FreeSignal(c2psig)
  154.                     ELSE PrintF('Can''t get c2p signal!\n')
  155.                 ENDIF
  156.  
  157.                 CloseRtgScreen(rsc)
  158.             ELSE PrintF('Can''t open rtg screen!\n')
  159.  
  160.             FreeRtgScreenModeReq(req)
  161.         ELSE PrintF('Can''t open rtg requester!\n')
  162.  
  163.         CloseLibrary(RTGMasterBase)
  164.     ELSE PrintF('Can''t open rtgmaster.library v23+!\n')
  165. ENDPROC
  166.  
  167. PROC LoadPalette(rsc,name:PTR TO CHAR)
  168.     DEF rgb[800]:ULONG,f
  169.     IF f:=Open(name,OLDFILE)
  170.         Read(f,rgb,FileLength(name))
  171.         LoadRGBRtg(rsc,rgb)
  172.         Close(f)
  173.     ENDIF
  174. ENDPROC
  175.  
  176. DEF    pool
  177.  
  178. OBJECT track
  179.     line:PTR TO PTR TO trackline,
  180.     count:WORD,
  181.     pos:F
  182.  
  183. OBJECT trackline
  184.     data:PTR TO trackdata,
  185.     x/y/z:F,                    // for camera interpolation
  186.     count:WORD
  187.  
  188. OBJECT trackdata
  189.     texture:WORD,            // TX...
  190.     x/y/z:FLOAT
  191.  
  192. ENUM    TX_End=0,
  193.         TX_Black=1,
  194.         TX_White=15,
  195.         TX_Yellow=88,
  196.         TX_Grass=58,
  197.         TX_Grass1=57,
  198.         TX_Grass2=56,
  199.         TX_Road=7
  200.  
  201. OBJECT kxy
  202.     kind:W,
  203.     x/y:F
  204.  
  205. OBJECT xyz
  206.     x/y/z:F
  207.  
  208. OBJECT xy
  209.     x/y:F
  210.  
  211. // this function loads/generates a track given by the argument 'n'
  212. // currently 0 is the only track supported
  213. PROC LoadTrack(n)(BOOL,PTR TO track)
  214.     SELECT n
  215.     CASE 0
  216.         DEF    profile:PTR TO kxy,pos:PTR TO xyz
  217.  
  218.         // profile definition, there is currently only one profile for whole track
  219.         profile:=[
  220.             TX_Grass2,-10.0,  3,
  221.             TX_Grass1, -7.0,  1,
  222.             TX_Grass,  -4.0,  0,
  223.             TX_White,  -3.0,  0,
  224.             TX_Road,   -2.8,  0,
  225.             TX_Yellow, -0.1,  0,
  226.             TX_Road,    0.1,  0,
  227.             TX_White,   2.8,  0,
  228.             TX_Grass,   3.0,  0,
  229.             TX_Grass1,  4.0,  0,
  230.             TX_Grass2,  7.0,  1,
  231.             TX_End,    10.0,  3]:kxy        // 12 pieces
  232.  
  233.         // profile positions
  234.         pos:=[
  235.             -50.0,0.0,-100.0,
  236.             -50.0,0.0, -90.0,
  237.             -50.0,0.0, -80.0,
  238.             -50.0,0.0, -70.0,
  239.             -50.0,0.0, -60.0,
  240.             -50.0,0.0, -50.0,
  241.             -50.0,0.0, -40.0,
  242.             -50.0,0.0, -30.0,
  243.             -50.0,0.0, -20.0,
  244.             -50.0,0.0, -10.0,        // 10
  245.  
  246.             -50.0,-0.1,  0.0,
  247.             -50.0,-0.2, 10.0,
  248.             -50.0,-0.3, 20.0,
  249.             -50.0,-0.4, 30.0,
  250.             -50.0,-0.4, 40.0,
  251.             -50.0,-0.4, 50.0,
  252.             -50.0,-0.4, 60.0,
  253.             -50.0,-0.3, 70.0,
  254.             -50.0,-0.2, 80.0,
  255.             -50.0,-0.1, 90.0,        // 20
  256.  
  257.             -50.0,0.0, 100.0,
  258.             -49.4,0.0, 107.8,
  259.             -47.6,0.0, 115.5,
  260.             -44.6,0.0, 122.7,
  261.             -40.5,0.0, 129.4,
  262.             -35.4,0.0, 135.4,
  263.             -29.4,0.0, 140.5,
  264.             -22.7,0.0, 144.6,
  265.             -15.5,0.0, 147.6,
  266.              -7.8,0.0, 149.4,        // 30
  267.  
  268.               0.0,0.0, 150.0,
  269.               7.8,0.0, 149.4,
  270.              15.5,0.0, 147.6,
  271.              22.7,0.0, 144.6,
  272.              29.4,0.0, 140.5,
  273.              35.4,0.0, 135.4,
  274.              40.5,0.0, 129.4,
  275.              44.6,0.0, 122.7,
  276.              47.6,0.0, 115.5,
  277.              49.4,0.0, 107.8,        // 40
  278.  
  279.              50.0,0.0, 100.0,
  280.              50.0,0.0,  90.0,
  281.              50.0,0.0,  80.0,
  282.              50.0,0.0,  70.0,
  283.              50.0,0.0,  60.0,
  284.              50.0,0.0,  50.0,
  285.              50.0,0.0,  40.0,
  286.              50.0,0.0,  30.0,
  287.              50.0,0.0,  20.0,
  288.              50.0,0.0,  10.0,        // 50
  289.  
  290.              50.0,0.0,   0.0,
  291.              50.0,0.0, -10.0,
  292.              50.0,0.0, -20.0,
  293.              50.0,0.0, -30.0,
  294.              50.0,0.0, -40.0,
  295.              50.0,0.0, -50.0,
  296.              50.0,0.0, -60.0,
  297.              50.0,0.0, -70.0,
  298.              50.0,0.0, -80.0,
  299.              50.0,0.0, -90.0,        // 60
  300.  
  301.              50.0,0.0,-100.0,
  302.              49.4,0.0,-107.8,
  303.              47.6,0.0,-115.5,
  304.              44.6,0.0,-122.7,
  305.              40.5,0.0,-129.4,
  306.              35.4,0.0,-135.4,
  307.              29.4,0.0,-140.5,
  308.              22.7,0.0,-144.6,
  309.              15.5,0.0,-147.6,
  310.               7.8,0.0,-149.4,        // 70
  311.  
  312.               0.0,0.0,-150.0,
  313.              -7.8,0.0,-149.4,
  314.             -15.5,0.0,-147.6,
  315.             -22.7,0.0,-144.6,
  316.             -29.4,0.0,-140.5,
  317.             -35.4,0.0,-135.4,
  318.             -40.5,0.0,-129.4,
  319.             -44.6,0.0,-122.7,
  320.             -47.6,0.0,-115.5,
  321.             -49.4,0.0,-107.8        // 80
  322.             ]:xyz
  323.  
  324.         DEF    track:PTR TO track,trackline:PTR TO trackline,trackdata:PTR TO trackdata,m
  325.         DEFF    cos,sin
  326.  
  327.         IFN track:=AllocPooled(pool,SIZEOF_track+SIZEOF_PTR*80) THEN RETURN FALSE,NIL
  328.         track.line:=track+SIZEOF_track
  329.         track.pos:=0
  330.  
  331.         FOR n:=0 TO 79
  332.  
  333.             IFN trackline:=AllocPooled(pool,SIZEOF_trackline) THEN RETURN FALSE,NIL
  334.             IFN trackdata:=AllocPooled(pool,SIZEOF_trackdata*12) THEN RETURN FALSE,NIL
  335.  
  336.             track.line[n]:=trackline
  337.  
  338.             // get needed sine and cosine for the correct profile angle
  339.             cos:=pos[n].x/50.0
  340.             IF pos[n].z>100
  341.                 sin:=(pos[n].z-100)/50.0
  342.             ELSEIF pos[n].z<-100
  343.                 sin:=(pos[n].z+100)/50.0
  344.             ELSE sin:=0
  345.  
  346.             // apply the sine and cosine to all the profile points
  347.             FOR m:=0 TO 11
  348.                 trackdata[m].texture:=profile[m].kind
  349.                 trackdata[m].x:=profile[m].x*cos+pos[n].x
  350.                 trackdata[m].y:=profile[m].y+pos[n].y
  351.                 trackdata[m].z:=profile[m].x*sin+pos[n].z
  352.             ENDFOR
  353.  
  354.             IF trackdata[5].texture=TX_Yellow AND Even(n) THEN trackdata[5].texture:=TX_Road
  355.  
  356.             trackline.x:=pos[n].x
  357.             trackline.y:=pos[n].y
  358.             trackline.z:=pos[n].z
  359.             trackline.data:=trackdata
  360.             trackline.count:=12
  361.  
  362.         ENDFOR
  363.  
  364.         track.count:=80
  365.     ENDSELECT
  366. ENDPROC TRUE,track
  367.  
  368. PROC UnLoadTrack(tr:PTR TO track)
  369.     // nothing to free, used pool is deleted in main()
  370. ENDPROC
  371.  
  372. OBJECT camera
  373.     x/y/z:FLOAT,        // camera position
  374.     ax/ay/az:FLOAT,    // camera angle
  375.     cx/cy/cz:FLOAT,    // camera angle cosine
  376.     sx/sy/sz:FLOAT,    // camera angle sine
  377.     l:FLOAT                // camera length
  378.  
  379. PROC RenderTrack(dst:PTR TO chunky,track:PTR TO track,c:PTR TO camera)
  380.     DEF    data:PTR TO trackdata,n,next:PTR TO trackdata
  381.     DEF    x0,y0,x1,y1,x2,y2,q=track.pos+30,sh,isok:BOOL,totok:BOOL
  382.     WHILE q>=track.pos
  383.         data:=track.line[q].data
  384.         next:=track.line[q+1].data
  385.         FOR n:=0 TO track.line[q].count-2
  386.             totok:=FALSE
  387.             x0,y0,isok:=ComputePersp(data[n].x,data[n].y,data[n].z,c);            totok|=isok
  388.             x1,y1,isok:=ComputePersp(data[n+1].x,data[n+1].y,data[n+1].z,c);    totok|=isok
  389.             x2,y2,isok:=ComputePersp(next[n].x,next[n].y,next[n].z,c);            totok|=isok
  390.  
  391.             polycount++
  392.             IF totok=FALSE
  393.                 x0+=dst.wi>>1
  394.                 y0+=dst.he>>1
  395.                 x1+=dst.wi>>1
  396.                 y1+=dst.he>>1
  397.                 x2+=dst.wi>>1
  398.                 y2+=dst.he>>1
  399.  
  400.                 // this is here only to compute a nicer colours for more distant profiles
  401.                 sh:=data[n].texture-Min(6,Abs(track.pos/2-q/2))
  402. //                sh:=data[n].texture
  403.  
  404.                 DrawTriangle(dst,[x0,y0,x1,y1,x2,y2]:xy,sh)
  405.                 polydraw++
  406.  
  407.                 x0,y0,isok:=ComputePersp(next[n+1].x,next[n+1].y,next[n+1].z,c);    totok|=isok
  408.                 polycount++
  409.                 IFN totok
  410.                     x0+=dst.wi>>1
  411.                     y0+=dst.he>>1
  412.  
  413.                     // this is the most important function call of this example, if it would be
  414.                     // more optimised, You would earn much more speed, wanna take a look at it? :)
  415.                     DrawTriangle(dst,[x0,y0,x1,y1,x2,y2]:xy,sh)
  416.                     polydraw++
  417.                 ENDIF
  418.             ENDIF
  419.  
  420.             IF Mouse()=2 THEN RETURN
  421.         ENDFOR
  422.         q--
  423.     ENDWHILE
  424. ENDPROC
  425.  
  426. PROC ComputePersp(x:F,y:F,z:F,c:PTR TO camera)(F,F,BOOL)
  427.     DEFF    x1,y1,z1,xx,yy,zz,l
  428.  
  429.     x:=c.x-x
  430.     y:=c.y-y+0.25
  431.     z:=c.z-z
  432.  
  433.     x1:=x*c.cz+y*c.sz
  434.     y1:=y*c.cz-x*c.sz
  435.     xx:=x1*c.cy+z*c.sy
  436.     z1:=z*c.cy-x1*c.sy
  437.     zz:=z1*c.cx+y1*c.sx
  438.     yy:=y1*c.cx-z1*c.sx
  439.  
  440.     zz+=c.l
  441.  
  442.     l:=c.l-zz
  443.     IF l>0.0
  444.         x:=xx*c.l/l
  445.         y:=yy*c.l/l
  446.     ELSE
  447.         RETURN 0,0,TRUE
  448.     ENDIF
  449.     transcount++
  450. ENDPROC x*10,y*10,FALSE
  451.  
  452. PROC MoveCamera(cam:PTR TO camera,tra:PTR TO track,delta:D)
  453.     DEFD    ax,ay,az,bx,by,bz
  454.     ax,ay,az:=GetTrackPos(tra,tra.pos)
  455.     cam.x:=ax
  456.     cam.y:=ay+1
  457.     cam.z:=az
  458.     ax,ay,az:=GetTrackPos(tra,tra.pos)
  459.     bx,by,bz:=GetTrackPos(tra,tra.pos+4)
  460.     IF bz-az<0
  461.         cam.ay:=PI-ATan((bx-ax)/(bz-az))
  462.     ELSE
  463.         cam.ay:=-ATan((bx-ax)/(bz-az))
  464.     ENDIF
  465. /*
  466.     DEFD    cx,cy,cz,dx,dy,dz
  467.     ax,ay,az:=GetTrackPos(tra,tra.pos)
  468.     bx,by,bz:=GetTrackPos(tra,tra.pos+5)
  469.     cx,cy,cz:=GetTrackPos(tra,tra.pos+0.2)
  470.     dx,dy,dz:=GetTrackPos(tra,tra.pos+0.2+5)
  471. //    cam.ay:=VectorAngle(bx-ax,by-ay,dx-cx,dy-cy)
  472. */
  473.     SetSinCos(cam)
  474.     tra.pos+=0.2
  475. ENDPROC
  476.  
  477. PROC GetTrackPos(tra:PTR TO track,pos:D)(D,D,D)
  478.     DEFD    x,y,z,dpos
  479.     DEFL    posl,posn
  480.     posl:=pos
  481.     dpos:=pos-posl
  482.     posn:=posl+1
  483.     WHILE posl>=80 DO posl-=80
  484.     WHILE posn>=80 DO posn-=80
  485.     x:=tra.line[posl].x*(1-dpos)+tra.line[posn].x*dpos
  486.     y:=tra.line[posl].y*(1-dpos)+tra.line[posn].y*dpos
  487.     z:=tra.line[posl].z*(1-dpos)+tra.line[posn].z*dpos
  488. ENDPROC x,y,z
  489.  
  490. PROC SetSinCos(c:PTR TO camera)
  491.     c.cx:=Cos(c.ax)
  492.     c.cy:=Cos(c.ay)
  493.     c.cz:=Cos(c.az)
  494.     c.sx:=Sin(c.ax)
  495.     c.sy:=Sin(c.ay)
  496.     c.sz:=Sin(c.az)
  497. ENDPROC
  498.  
  499. // time computing routines
  500. MODULE    'devices/timer','timer'
  501.  
  502. DEF    TimerBase
  503. DEF    timerio:TimeRequest,
  504.         time0:EClockVal,
  505.         time1:EClockVal,
  506.         micros_per_eclock:DOUBLE,
  507.         timerclosed,
  508.         polycount,
  509.         polydraw,
  510.         transcount
  511.  
  512. PROC get_timer()(L)
  513.     DEFL    ok=0
  514.     IFN timerclosed:=OpenDevice('timer.device',UNIT_VBLANK,timerio,0)
  515.         TimerBase:=timerio.IO.Device
  516.         micros_per_eclock:=1000000.0/ReadEClock(time0)
  517.         ok:=1
  518.     ENDIF
  519. ENDPROC ok
  520.  
  521. PROC free_timer()
  522.     IFN timerclosed THEN CloseDevice(timerio)
  523. ENDPROC
  524.